pytest, xdist, coverage
pytest と pytest-xdist を使ってマルチプロセスでテストを並列実行したあと、coveragepyでカバレッジを収集する。
という話がPyPI (warehouse) の開発blogで紹介されていた。
Making PyPI's test suite 81% faster - The Trail of Bits Blog
実際にやってみると、coverageが1プロセス分しか取得できない。
coveragepy のマルチプロセス環境下での動作
Measuring subprocesses — Coverage.py 7.9.1 documentation
マルチプロセスで起動した先でもカバレッジ収集を開始するには明示的に設定が必要
parallel = true を指定
COVERAGE_PROCESS_START 環境変数に設定ファイルを明示して参照できるようにする
coverage.process_startup() をサブプロセス側で実行
この実行を sitecustomize.py で行うか、pthファイルで行う
code:sitecustomize.py
try:
import coverage
coverage.process_startup()
except ImportError:
pass
pthファイルはできれば使いたくないのだけど...
調べてみると、どうも sitecustomize.py がpytestの子プロセス側で実行されていない。
sys.path に設定されたPYTHONPATHにあっても、親プロセスも含めて一度も読み込まれていない。
なにかがおかしい。
うまくいっていない報告がいくつか見つかった
"source" config combined with pytest-xdist leads to incorrect coverage · Issue #1341 · nedbat/coveragepy · GitHub
coverage-enable-subprocess をインストールする
pytest-cov を使う(生coverageではなく)
https://stackoverflow.com/questions/72840168/how-to-run-coverage-report-with-parallel-pytest-using-xdist-and-django-coverage
coverage-enable-subprocess をインストールしてもだめだった
pytest-cov を使うことにした
coverage-enable-subprocess がやっていること
https://github.com/bukzor/python-coverage-enable-subprocess/blob/master/setup.py
インストール時に coverage-enable-subprocess.pth ファイルを作成
code:coverage-enable-subprocess.pth
try:
import coverage
except (ImportError, OSError):
pass
else:
coverage.process_startup()
自分でpthファイルを作成せずに代わりに作成してくれる便利パッケージでした
attrs でも採用されている、と前述のissueに書いてあった
https://github.com/python-attrs/attrs/pull/1011/files#diff-60f61ab7a8d1910d86d9fda2261620314edcae5894d5aaa236b821c7256badd7R67
結局、おとなしく coverage-enable-subprocess をインストールして完了とした。
(後で書く)完成形の設定ひととおり